<template>
  <el-dialog
    v-model="dialogVisible"
    :title="isEdit ? '编辑博客' : '新增博客'"
    width="900px"
    :close-on-click-modal="false"
    @close="handleClose"
  >
    <el-form
      ref="formRef"
      :model="form"
      :rules="rules"
      label-width="100px"
    >
      <el-form-item label="标题" prop="title">
        <el-input
          v-model="form.title"
          placeholder="请输入博客标题"
          clearable
        />
      </el-form-item>
      
      <el-form-item label="分类" prop="category_ids">
        <el-select
          v-model="form.category_ids"
          multiple
          filterable
          :reserve-keyword="false"
          placeholder="请选择分类"
          style="width: 100%"
        >
          <el-option
            v-for="category in categoryOptions"
            :key="category.id"
            :label="category.name"
            :value="category.id"
          />
        </el-select>
      </el-form-item>
      
      <el-form-item label="摘要" prop="summary">
        <el-input
          v-model="form.summary"
          type="textarea"
          :rows="3"
          placeholder="请输入博客摘要"
          maxlength="200"
          show-word-limit
        />
      </el-form-item>
      
      <el-form-item label="封面" prop="cover">
        <div class="cover-upload-container">
          <el-radio-group v-model="coverType" class="cover-type-selector">
            <el-radio label="url">链接</el-radio>
            <el-radio label="upload">上传</el-radio>
          </el-radio-group>
          
          <div v-if="coverType === 'url'" class="cover-url-input">
            <el-input
              v-model="form.cover"
              placeholder="请输入封面图片URL"
              clearable
            />
          </div>
          
          <div v-else class="cover-upload-wrapper">
            <el-upload
              class="cover-uploader"
              :action="uploadAction"
              :headers="uploadHeaders"
              :show-file-list="false"
              :on-success="handleUploadSuccess"
              :on-error="handleUploadError"
              :before-upload="beforeUpload"
              :http-request="handleCustomUpload"
              accept="image/*"
            >
              <el-image
                v-if="form.cover"
                :src="form.cover"
                class="cover-image"
                fit="cover"
                v-loading="uploadLoading"
              />
              <div v-else class="cover-uploader-icon-wrapper" v-loading="uploadLoading">
                <el-icon class="cover-uploader-icon"><Plus /></el-icon>
                <div class="upload-text">点击上传</div>
              </div>
            </el-upload>
            <div v-if="form.cover" class="cover-actions">
              <el-button
                type="danger"
                size="small"
                :icon="Delete"
                @click="handleRemoveCover"
              >
                删除
              </el-button>
            </div>
          </div>
          
          <div v-if="form.cover" class="cover-preview">
            <el-image
              :src="form.cover"
              fit="cover"
              style="width: 200px; height: 120px; border-radius: 4px; margin-top: 10px;"
              :preview-src-list="[form.cover]"
            />
          </div>
        </div>
      </el-form-item>
      
      <el-form-item label="标签" prop="tag_ids">
        <el-select
          v-model="form.tag_ids"
          multiple
          filterable
          :reserve-keyword="false"
          placeholder="请选择标签"
          style="width: 100%"
        >
          <el-option
            v-for="tag in tagOptions"
            :key="tag.id"
            :label="tag.name"
            :value="tag.id"
          />
        </el-select>
      </el-form-item>
      
      <el-form-item label="内容" prop="content">
        <div class="editor-container">
          <QuillEditor
            v-model:content="form.content"
            contentType="html"
            theme="snow"
            :toolbar="toolbarOptions"
            style="height: 400px"
          />
        </div>
      </el-form-item>
      
    </el-form>
    
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="handleClose">取消</el-button>
        <el-button type="primary" :loading="loading" @click="handleSubmit">
          确定
        </el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { ref, reactive, computed, watch } from 'vue'
import { ElMessage, FormInstance, FormRules } from 'element-plus'
import { Plus, Delete } from '@element-plus/icons-vue'
import { QuillEditor } from '@vueup/vue-quill'
import '@vueup/vue-quill/dist/vue-quill.snow.css'
import { createBlog, updateBlog, getBlogDetail, uploadImage } from '@/api/blogs'
import { getCategoryList } from '@/api/categories'
import { getTagList } from '@/api/tags'

interface BlogForm {
  title: string
  content: string
  summary: string
  cover: string
  status: number
  category_ids: string[]
  tag_ids: string[]
}

interface Category {
  id: string
  name: string
}

interface Tag {
  id: string
  name: string
}

const props = defineProps<{
  modelValue: boolean
  blogId?: string | null
}>()

const emit = defineEmits<{
  'update:modelValue': [value: boolean]
  'success': []
}>()

const formRef = ref<FormInstance | null>(null)
const loading = ref(false)
const coverType = ref<'url' | 'upload'>('url')
const uploadLoading = ref(false)
const categoryOptions = ref<Category[]>([])
const tagOptions = ref<Tag[]>([])
const categoryLoading = ref(false)
const tagLoading = ref(false)

// 上传配置
const uploadAction = computed(() => {
  // 开发环境使用 mock，生产环境使用真实 API
  const USE_MOCK = import.meta.env.DEV && (import.meta.env.VITE_USE_MOCK !== 'false')
  if (USE_MOCK) {
    // Mock 上传，返回一个模拟的 URL
    return '#'
  }
  // 真实 API 地址
  const baseURL = import.meta.env.DEV 
    ? (import.meta.env.VITE_API_BASE_URL || '/devApi')
    : (import.meta.env.VITE_API_URL || import.meta.env.VITE_API_BASE_URL || '/api')
  return `${baseURL}/upload/image`
})

const uploadHeaders = computed(() => {
  const token = localStorage.getItem('portal-web-token')
  return token ? { Authorization: `Bearer ${token}` } : {}
})

const dialogVisible = computed({
  get: () => props.modelValue,
  set: (val: boolean) => emit('update:modelValue', val)
})

const isEdit = computed(() => !!props.blogId)

const form = reactive<BlogForm>({
  title: '',
  content: '',
  summary: '',
  cover: '',
  status: 0, // 新增默认草稿
  category_ids: [],
  tag_ids: []
})

const rules: FormRules<BlogForm> = {
  title: [
    { required: true, message: '请输入博客标题', trigger: 'blur' }
  ],
  content: [
    { required: true, message: '请输入博客内容', trigger: 'blur' }
  ]
}

// 富文本编辑器工具栏配置
const toolbarOptions = [
  ['bold', 'italic', 'underline', 'strike'],
  ['blockquote', 'code-block'],
  [{ 'header': 1 }, { 'header': 2 }],
  [{ 'list': 'ordered' }, { 'list': 'bullet' }],
  [{ 'script': 'sub' }, { 'script': 'super' }],
  [{ 'indent': '-1' }, { 'indent': '+1' }],
  [{ 'direction': 'rtl' }],
  [{ 'size': ['small', false, 'large', 'huge'] }],
  [{ 'header': [1, 2, 3, 4, 5, 6, false] }],
  [{ 'color': [] }, { 'background': [] }],
  [{ 'font': [] }],
  [{ 'align': [] }],
  ['clean'],
  ['link', 'image', 'video']
]

// 获取分类列表
const fetchCategoryList = async (): Promise<void> => {
  categoryLoading.value = true
  try {
    const res = await getCategoryList({ pageSize: 100 })
    if (res.code === 200 && res.data) {
      categoryOptions.value = res.data.list || []
    }
  } catch (error) {
    console.error('获取分类列表失败:', error)
  } finally {
    categoryLoading.value = false
  }
}

// 获取标签列表
const fetchTagList = async (): Promise<void> => {
  tagLoading.value = true
  try {
    const res = await getTagList({ pageSize: 100 })
    if (res.code === 200 && res.data) {
      tagOptions.value = res.data.list || []
    }
  } catch (error) {
    console.error('获取标签列表失败:', error)
  } finally {
    tagLoading.value = false
  }
}

// 获取博客详情
const fetchBlogDetail = async (): Promise<void> => {
  if (!props.blogId) return
  
  loading.value = true
  try {
    const res = await getBlogDetail({ id: props.blogId })
    if (res.code === 200 && res.data) {
      // 处理分类和标签 - 从 categories 和 tags 数组中提取 ID
      let categoryIds: string[] = []
      let tagIds: string[] = []
      
      // 如果后端返回的是 categories 数组（API 文档格式）
      if (res.data.categories && Array.isArray(res.data.categories)) {
        categoryIds = res.data.categories.map((cat: any) => cat.id).filter(Boolean)
      } else if (res.data.category_ids && Array.isArray(res.data.category_ids)) {
        // 兼容旧格式
        categoryIds = res.data.category_ids
      }
      
      // 如果后端返回的是 tags 数组（API 文档格式）
      if (res.data.tags && Array.isArray(res.data.tags)) {
        tagIds = res.data.tags.map((tag: any) => tag.id).filter(Boolean)
      } else if (res.data.tag_ids && Array.isArray(res.data.tag_ids)) {
        // 兼容旧格式
        tagIds = res.data.tag_ids
      }
      
      Object.assign(form, {
        title: res.data.title || '',
        content: res.data.content || '',
        summary: res.data.summary || '',
        cover: res.data.cover || '',
        category_ids: categoryIds,
        tag_ids: tagIds,
        status: res.data.status !== undefined ? res.data.status : 0
      })
      // 根据封面 URL 判断是链接还是上传的图片
      if (form.cover) {
        coverType.value = form.cover.startsWith('data:') || form.cover.startsWith('blob:') ? 'upload' : 'url'
      } else {
        coverType.value = 'url'
      }
    }
  } catch (error) {
    console.error('获取博客详情失败:', error)
  } finally {
    loading.value = false
  }
}

// 重置表单数据和状态
const resetForm = (): void => {
  Object.assign(form, {
    title: '',
    content: '',
    summary: '',
    cover: '',
    category_ids: [],
    tag_ids: [],
    status: 0 // 新增默认草稿
  })
  coverType.value = 'url'
  // 清空校验状态
  if (formRef.value) {
    formRef.value.clearValidate()
    formRef.value.resetFields()
  }
}

// 监听对话框打开
watch(dialogVisible, (visible: boolean): void => {
  if (visible) {
    // 先重置表单数据和校验状态
    resetForm()
    
    // 加载分类和标签列表
    fetchCategoryList()
    fetchTagList()
    
    // 如果是编辑模式，加载博客详情
    if (isEdit.value && props.blogId) {
      fetchBlogDetail()
    }
  }
})

// 监听 blogId 变化（处理从编辑切换到新增的情况）
watch(() => props.blogId, (newId) => {
  // 如果对话框是打开的，且 blogId 发生变化，需要重置表单
  if (dialogVisible.value) {
    resetForm()
    // 如果有新的 blogId，加载详情；否则保持空表单（新增模式）
    if (newId) {
      fetchBlogDetail()
    }
  }
})

const handleClose = (): void => {
  dialogVisible.value = false
  // 关闭时重置表单（延迟执行，避免关闭动画时看到表单重置）
  setTimeout(() => {
    resetForm()
  }, 300)
}

// 上传前验证
const beforeUpload = (file: File): boolean => {
  const isImage = file.type.startsWith('image/')
  const isLt5M = file.size / 1024 / 1024 < 5

  if (!isImage) {
    ElMessage.error('只能上传图片文件!')
    return false
  }
  if (!isLt5M) {
    ElMessage.error('图片大小不能超过 5MB!')
    return false
  }
  return true
}

// 自定义上传
const handleCustomUpload = async (options: any): Promise<void> => {
  uploadLoading.value = true
  const file = options.file
  
  // Mock 模式：使用 FileReader 转换为 base64
  const USE_MOCK = import.meta.env.DEV && (import.meta.env.VITE_USE_MOCK !== 'false')
  if (USE_MOCK) {
    const reader = new FileReader()
    reader.onload = (e) => {
      const result = e.target?.result as string
      form.cover = result
      uploadLoading.value = false
      ElMessage.success('上传成功')
    }
    reader.onerror = () => {
      uploadLoading.value = false
      ElMessage.error('读取文件失败')
    }
    reader.readAsDataURL(file)
    return
  }
  
  // 真实 API 模式
  try {
    const formData = new FormData()
    formData.append('file', file)
    
    const res = await uploadImage(formData)
    if (res.code === 200 && res.data) {
      form.cover = res.data.url || res.data
      ElMessage.success('上传成功')
    } else {
      ElMessage.error(res.message || '上传失败')
    }
  } catch (error) {
    ElMessage.error('上传失败，请重试')
  } finally {
    uploadLoading.value = false
  }
}

// 上传成功（兼容 Element Plus 的 on-success）
const handleUploadSuccess = async (): Promise<void> => {
  // 这个方法不会被调用，因为我们使用了 http-request
}

// 上传失败
const handleUploadError = (): void => {
  uploadLoading.value = false
  ElMessage.error('上传失败，请重试')
}

// 删除封面
const handleRemoveCover = (): void => {
  form.cover = ''
}

const handleSubmit = async (): Promise<void> => {
  if (!formRef.value) return
  
  await formRef.value.validate(async (valid: boolean) => {
    if (valid) {
      // 检查内容是否为空（去除HTML标签后）
      const textContent = form.content.replace(/<[^>]*>/g, '').trim()
      if (!textContent) {
        ElMessage.warning('请输入博客内容')
        return
      }
      
      loading.value = true
      try {
        // 准备提交数据，使用 category_ids 和 tag_ids
        const submitData: any = {
          title: form.title,
          content: form.content,
          summary: form.summary,
          cover: form.cover,
          status: form.status
        }
        
        // 如果有选中的分类，添加 category_ids
        if (form.category_ids.length > 0) {
          submitData.category_ids = form.category_ids
        }
        
        // 如果有选中的标签，添加 tag_ids
        if (form.tag_ids.length > 0) {
          submitData.tag_ids = form.tag_ids
        }
        
        if (isEdit.value && props.blogId) {
          await updateBlog({
            id: props.blogId,
            ...submitData
          })
          ElMessage.success('更新成功')
        } else {
          await createBlog(submitData)
          ElMessage.success('创建成功')
        }
        
        emit('success')
        handleClose()
      } catch (error) {
        console.error('保存博客失败:', error)
      } finally {
        loading.value = false
      }
    }
  })
}
</script>

<style lang="scss" scoped>
.dialog-footer {
  text-align: right;
}

.editor-container {
  :deep(.ql-container) {
    min-height: 300px;
  }
  
  :deep(.ql-editor) {
    min-height: 300px;
  }
}

.cover-upload-container {
  width: 100%;
  
  .cover-type-selector {
    margin-bottom: 12px;
  }
  
  .cover-url-input {
    width: 100%;
  }
  
  .cover-upload-wrapper {
    .cover-uploader {
      :deep(.el-upload) {
        border: 1px dashed #d9d9d9;
        border-radius: 6px;
        cursor: pointer;
        position: relative;
        overflow: hidden;
        transition: all 0.3s;
        width: 200px;
        height: 120px;
        
        &:hover {
          border-color: #409eff;
        }
      }
      
      .cover-image {
        width: 200px;
        height: 120px;
        display: block;
      }
      
      .cover-uploader-icon-wrapper {
        width: 200px;
        height: 120px;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        color: #8c939d;
        background-color: #fafafa;
        
        .cover-uploader-icon {
          font-size: 28px;
          margin-bottom: 8px;
        }
        
        .upload-text {
          font-size: 14px;
        }
      }
    }
    
    .cover-actions {
      margin-top: 10px;
    }
  }
  
  .cover-preview {
    margin-top: 10px;
  }
}
</style>

